home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / WAIS / ir / ircfiles.c.orig < prev    next >
Encoding:
Text File  |  1992-02-02  |  15.3 KB  |  773 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    Brewster@think.com
  6. */
  7.  
  8. /* this file defines a set of helper functions
  9.  * for indexing common types of files.
  10.  * -brewster 7/90
  11.  */
  12.  
  13. /* I encourage adding customizations.
  14.  * (too bad they all have to be hard coded, but
  15.  *  C did not have convenient dynamic linking facilities)
  16.  *
  17.  * Add three functions to this file:
  18.  * boolean foo_separator_function(char *line){}
  19.  * void foo_header_function(char *line){}
  20.  * long foo_date_function(char *line){}
  21.  * void foo_finish_header_function(char *header){}
  22.  *
  23.  * then add the prototypes to ircfiles.h
  24.  * then add the functions to the big case statement in irbuild.c
  25.  *
  26.  *
  27.  * to do:
  28.  *   filter for digests
  29.  *
  30.  */
  31.  
  32.  
  33. /* Change log:
  34.  * 8/90 brewster added the library customizations
  35.  * 6/91 and before - added a bunch of other filters - JG
  36.  */
  37.  
  38. #include <string.h>
  39. #include <ctype.h>
  40. #include "cutil.h"
  41. #include "ircfiles.h"
  42.  
  43. #define MAX_HEADER_LEN 100
  44.  
  45. static char* trim_trailing_newline _AP((char* string));
  46.  
  47. static char*
  48. trim_trailing_newline(string)
  49. char* string;
  50. {
  51.   if(string)
  52.     if(strlen(string) > 0)
  53.       if(string[strlen(string) -1] == '\n')
  54.     string[strlen(string) -1] = '\0';
  55.   return(string);
  56. }
  57.  
  58. /* =================================
  59.  * ===  Groliers Customizations  ===
  60.  * =================================
  61.  */
  62.  
  63. boolean groliers_separator_function(line)
  64. char *line;
  65. {
  66.   if((strlen(line) > strlen("ARTICLE")) &&
  67.      substrcmp(line, "ARTICLE")){
  68.     /* printf("hit %s\n", line); */
  69.     return(true);
  70.   }
  71.   else{
  72.     return(false);
  73.   }
  74. }
  75.  
  76. char groliers_header[MAX_HEADER_LEN + 1];
  77.  
  78. void groliers_header_function(line)
  79. char *line;
  80. {
  81.   if(groliers_separator_function(line)){
  82.     strncpy(groliers_header, line + strlen("ARTICLE") + 2, MAX_HEADER_LEN);
  83.   }
  84. }
  85.  
  86. void groliers_finish_header_function(header)
  87. char *header;
  88. {
  89.   if(strlen(groliers_header) == 0){
  90.     strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  91.   }
  92.   else{
  93.     strncpy(header, groliers_header, MAX_HEADER_LEN);
  94.   }
  95.   groliers_header[0] = '\0';
  96. }
  97.  
  98.  
  99. /* ==============================
  100.  * ===  RMail Customizations  ===
  101.  * ==============================
  102.  */
  103.  
  104. /* this is just a preliminary version. A good version would
  105.  * produce a headline like gnu emacs RMAIL
  106.  */
  107.  
  108.  
  109. boolean mail_separator_function(line)
  110. char *line;
  111. {
  112.   /* this should really look for a "<cr><cr>From " rather than "<cr>From " */
  113.   if((strlen(line) > strlen("From ")) &&
  114.      substrcmp(line, "From ")){
  115.     return(true);
  116.   }
  117.   else{
  118.     return(false);
  119.   }
  120. }
  121.  
  122. boolean rmail_separator_function(line)
  123. char *line;
  124. {
  125.   if(0 == strcmp(line, " \n")){
  126.     return(true);
  127.   }
  128.   else{
  129.     return(false);
  130.   }
  131. }
  132.  
  133. /* This one is portable, but might get the wrong answer.
  134.    I'm open to better code.  - Jonny G
  135. */
  136.  
  137. static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  138.             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
  139.  
  140. long getdate(line)
  141. char *line;
  142. {
  143.   char date[255], *temp;
  144.   int day, month, year;
  145.   char cmonth[25];
  146.  
  147.   strcpy(date, line);
  148.  
  149.   temp = date;
  150.  
  151.   while(!isdigit(*temp)) temp++;
  152.  
  153.   sscanf(temp, "%d %s %d", &day, cmonth, &year);
  154.  
  155.   for(month = 0; months[month] != NULL; month++)
  156.     if(!strcmp(cmonth, months[month])) break;
  157.  
  158.   if (year > 99) year = year % 100;
  159.  
  160.   if(day > 0 && 
  161.      month < 12 &&
  162.      year > 0) {
  163.     return (10000 * year + 100 * (month+1) + day);
  164.   }
  165.   sscanf(temp, "%d/%d/%d", &month, &day, &year);
  166.  
  167.   if (year > 99) year = year % 100;
  168.  
  169.   if(day > 0 && 
  170.      month < 12 &&
  171.      year > 0) {
  172.     return (10000 * year + 100 * (month+1) + day);
  173.   }
  174.   sscanf(temp, "%d/%d/%d", &year, &month, &day);
  175.  
  176.   if (year > 99) year = year % 100;
  177.  
  178.   if(day > 0 && 
  179.      month < 12 &&
  180.      year > 0) {
  181.     return (10000 * year + 100 * (month+1) + day);
  182.   }
  183.   return 0;
  184. }
  185.  
  186. long mail_date_function(line)
  187. char *line;
  188. {
  189.   if((strlen(line) > strlen("Date: ")) &&
  190.      substrcmp(line, "Date: ")){
  191.     return(getdate(line+6));
  192.   }
  193.   else return -1;
  194. }
  195.  
  196.   
  197.  
  198. char mail_subject[MAX_HEADER_LEN + 1];
  199. char mail_from[MAX_HEADER_LEN + 1];
  200.  
  201. void mail_header_function(line)
  202. char *line;
  203. {
  204.   if((strlen(line) > strlen("Subject: ")) &&
  205.      substrcmp(line, "Subject: ") &&
  206.      (strlen(mail_subject) == 0)){
  207.     strcpy(mail_subject, "Re: ");
  208.     s_strncat(mail_subject, line + strlen("Subject: "), MAX_HEADER_LEN, MAX_HEADER_LEN);
  209.     trim_trailing_newline(mail_subject);
  210.   }
  211.   else if((strlen(line) > strlen("From: ")) &&
  212.      substrcmp(line, "From: ") &&
  213.      (strlen(mail_from) == 0)){
  214.     /* this should find the <foo@bar> field in the from list */
  215.     strncpy(mail_from, line + strlen("From: "), MAX_HEADER_LEN);
  216.     trim_trailing_newline(mail_from);
  217.   }
  218.   
  219. }
  220.  
  221. void mail_finish_header_function(header)
  222. char *header;
  223. {
  224.   if(strlen(mail_subject) != 0 &&
  225.      strlen(mail_from) != 0){
  226.     /* trim the from line if needed */
  227.     if(strlen(mail_from) > 10){
  228.       mail_from[10] = '\0';
  229.     }
  230.     strncpy(header, mail_from, MAX_HEADER_LEN);
  231.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  232.     s_strncat(header, mail_subject, MAX_HEADER_LEN, MAX_HEADER_LEN);
  233.     /* printf("%s\n", header); */
  234.   }
  235.   else if(strlen(mail_subject) != 0){
  236.     strncpy(header, mail_subject, MAX_HEADER_LEN);
  237.   }
  238.   else if(strlen(mail_from) != 0){
  239.     strncpy(header, mail_from, MAX_HEADER_LEN);
  240.   }
  241.   else{
  242.     strcpy(header, "Unknown Subject");
  243.   }
  244.   mail_from[0] = '\0';
  245.   mail_subject[0] = '\0';
  246. }
  247.  
  248.  
  249.  
  250.  
  251. boolean mail_or_rmail_separator(line)
  252. char *line;
  253. {
  254.   static boolean blank_line = false;
  255.  
  256.   if((strlen(line) > strlen("From ")) &&
  257.      substrcmp(line, "From ") &&
  258.      blank_line == true){
  259.     blank_line = false;
  260.     return(true);
  261.   }
  262.   
  263.   if(substrcmp(line, "")){
  264.     blank_line = true;
  265.     return(true);
  266.   }    
  267.   
  268.   if(!strcmp(line, "\n")){
  269.       blank_line = true;
  270.     }
  271.     else{
  272.       blank_line = false;
  273.     }
  274.  
  275.   return(false);
  276. }
  277.  
  278.  
  279. /* ========================================
  280.  * ===  Mail Digest Customizations     ====
  281.  * ========================================
  282.  */
  283.  
  284. boolean mail_digest_separator_function(line)
  285. char *line;
  286. {
  287.   if((strlen(line) > strlen("-----------------------------")) &&
  288.      substrcmp(line, "------------------------------")){
  289.     return(true);
  290.   }
  291.   else{
  292.     return(false);
  293.   }
  294. }
  295.  
  296.  
  297. /* ========================================
  298.  * ===  Library Catalog Customizations  ===
  299.  * ========================================
  300.  */
  301.  
  302. /* just use the title */
  303.  
  304. boolean catalog_separator_function(line)
  305. char *line;
  306. {
  307.   if((strlen(line) > strlen("Call:")) &&
  308.      (substrcmp(line, "Call:"))){
  309.     return(true);
  310.   }
  311.   else{
  312.     return(false);
  313.   }
  314. }
  315.  
  316. char catalog_header[MAX_HEADER_LEN + 1];
  317.  
  318. void catalog_header_function(line)
  319. char *line;
  320. {
  321.   if((strlen(line) > strlen("Title:")) && 
  322.      (substrcmp(line, "Title:"))){    
  323.     strncpy(catalog_header, line + strlen("Title:"), MAX_HEADER_LEN);
  324.   }
  325. }
  326.  
  327. void catalog_finish_header_function(header)
  328. char *header;
  329. {
  330.   if(strlen(catalog_header) == 0){
  331.     strcpy(header, "Unknown Title");
  332.   }
  333.   else{
  334.     strncpy(header, catalog_header, MAX_HEADER_LEN);
  335.   }
  336.   catalog_header[0] = '\0';
  337. }
  338.  
  339.  
  340.  
  341. /* ============================
  342.  * ===  Bio Customizations  ===
  343.  * ============================
  344.  */
  345.  
  346. /* customizations for a DB of genetic abstracts */
  347.  
  348. boolean hit_header = false;
  349.  
  350. boolean bio_separator_function(line)
  351. char *line;
  352. {
  353.   if((strlen(line) > strlen(">>>")) &&
  354.      substrcmp(line, ">>>")){
  355.     return(true);
  356.   }
  357.   else{
  358.     return(false);
  359.   }
  360. }
  361.  
  362. char bio_header[MAX_HEADER_LEN + 1];
  363.  
  364. void bio_header_function(line)
  365. char *line;
  366.  
  367. {
  368.   if(hit_header            /* we just hit a seperator previous to this */
  369.      && (!bio_separator_function(line)) /* we are not on the separator now */
  370.      && strlen(bio_header) == 0){ /* and we have not saved the headline yet */
  371.     strcpy(bio_header, line);
  372.     waislog(WLOG_MEDIUM, WLOG_INDEX, "storing line: %s", bio_header);
  373.     hit_header = false;
  374.   }
  375. }
  376.  
  377. void bio_finish_header_function(header)
  378. char *header;
  379.  
  380. {
  381.   hit_header = true; /* turn on the flag */
  382.   if(strlen(bio_header) == 0){
  383.     strcpy(header, "Unknown Title");
  384.   }
  385.   else{
  386.     strcpy(header, bio_header);
  387.   }
  388.   bio_header[0] = '\0';
  389. }
  390.  
  391. /* =================================
  392.  * ===  CMApp   Customizations  ===
  393.  * =================================
  394.  */
  395.  
  396. boolean cmapp_separator_function(line)
  397. char *line;
  398. {
  399.   if((strlen(line) > strlen("@A")) &&
  400.      substrcmp(line, "@A")){
  401.     /* printf("hit %s\n", line); */
  402.     return(true);
  403.   }
  404.   else{
  405.     return(false);
  406.   }
  407. }
  408.  
  409. char cmapp_header[MAX_HEADER_LEN + 1];
  410.  
  411. void cmapp_header_function(line)
  412. char *line;
  413. {
  414.   if((strlen(line) > strlen("APPLICATION:")) &&
  415.      substrcmp(line, "APPLICATION:")){
  416.     /* printf("hit %s\n", line); */
  417.     strncpy(cmapp_header, line + strlen("APPLICATION:"), MAX_HEADER_LEN);
  418.   }
  419. }
  420.  
  421. void cmapp_finish_header_function(header)
  422. char *header;
  423. {
  424.   if(strlen(cmapp_header) == 0){
  425.     strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  426.   }
  427.   else{
  428.     strncpy(header, cmapp_header, MAX_HEADER_LEN);
  429.   }
  430.   cmapp_header[0] = '\0';
  431. }
  432.  
  433. /* =================================
  434.  * ===  Jargon   Customizations  ===
  435.  * =================================
  436.  */
  437.  
  438. boolean jargon_separator_function(line)
  439. char *line;
  440. {
  441.   if((strlen(line) > 0) && line[0] =='<'){
  442.     /* printf("hit %s\n", line); */
  443.     return(true);
  444.   }
  445.   else{
  446.     return(false);
  447.   }
  448. }
  449.  
  450. char jargon_header[MAX_HEADER_LEN + 1];
  451.  
  452. void jargon_header_function(line)
  453. char *line;
  454. {
  455.   if((strlen(line) > 0) && line[0] =='<'){
  456.     char *end_ptr = strchr(line, '>');
  457.     if(NULL != end_ptr){
  458.       strncpy(jargon_header, (1+ line), MIN(MAX_HEADER_LEN, end_ptr - line));
  459.       jargon_header[end_ptr-line-1] = '\0';
  460.     }
  461.   }
  462. }    
  463.  
  464. void jargon_finish_header_function(header)
  465. char *header;
  466. {
  467.   if(strlen(jargon_header) == 0){
  468.     strncpy(header, "Introduction to the Jargon file", MAX_HEADER_LEN);
  469.   }
  470.   else{
  471.     strncpy(header, jargon_header, MAX_HEADER_LEN);
  472.   }
  473.   jargon_header[0] = '\0';
  474. }
  475.  
  476.  
  477.  
  478. /* =================================
  479.  * ===  Internet Resource Guide  ===
  480.  * =================================
  481.  */
  482.  
  483.  
  484. char irg_header[MAX_HEADER_LEN + 1];
  485. boolean irg_header_set = FALSE;
  486.  
  487. boolean irg_separator_function(line)
  488. char *line;
  489. {
  490.   if(line[0] == 12){  /* control L */
  491.     irg_header_set = FALSE;
  492.     return(true);
  493.   }
  494.   else
  495.     return(false);
  496. }
  497.  
  498. void irg_header_function(line)
  499. char *line;
  500. {
  501.   if((irg_header_set == FALSE) &&
  502.      (line[0] == 32 )){ /* space */
  503.     strncpy(irg_header, line + strspn(line, " "), MAX_HEADER_LEN);
  504.     irg_header_set = TRUE;
  505.   }
  506.   
  507. }
  508.  
  509. void irg_finish_header_function(header)
  510. char *header;
  511. {
  512.   if(strlen(irg_header) == 0){
  513.     strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  514.   }
  515.   else{
  516.     strncpy(header, irg_header, MAX_HEADER_LEN);
  517.   }
  518.   irg_header[0] = '\0';
  519.   irg_header_set = FALSE;
  520. }
  521.  
  522. /* ========================
  523.  * ===  Dash Separator  ===
  524.  * ========================
  525.  */
  526.  
  527.  
  528. /*
  529.  * dash-seperate entries
  530.  * used in Introduction to Algorithms bug.list, suggestions, etc.
  531.  * --------------------... at least 20 dashes
  532.  * header
  533.  * item
  534.  *  ..
  535.  * --------------------... at least 20 dashes
  536.  */
  537.  
  538. boolean dash_hit_header = false;
  539.  
  540. boolean dash_separator_function(line)
  541. char *line;
  542. {
  543.   if((strlen(line) > 20) && substrcmp(line,"--------------------")){
  544.     /* printf("hit %s\n", line); */
  545.     return(true);
  546.   }
  547.   else{
  548.     return(false);
  549.   }
  550. }
  551.  
  552. char dash_header[MAX_HEADER_LEN + 1];
  553.  
  554. void dash_header_function(line)
  555. char *line;
  556. {
  557.   if(dash_hit_header
  558.      && (!dash_separator_function(line))
  559.      && strlen(dash_header) == 0) {
  560.     strncpy(dash_header, line, MAX_HEADER_LEN);
  561.     dash_hit_header = false;
  562.   }
  563. }
  564.  
  565. void dash_finish_header_function(header)
  566. char *header;
  567.  
  568. {
  569.   dash_hit_header = true; /* turn on the flag */
  570.   if (strlen(dash_header) == 0) {
  571.     strcpy(header, "No Title");
  572.   }
  573.   else {
  574.     strncpy(header, dash_header, MAX_HEADER_LEN);
  575.   }
  576.   dash_header[0] = '\0';
  577. }
  578.  
  579.  
  580. /* ============================
  581.  * ===  one_line Separator  ===
  582.  * ============================
  583.  */
  584.  
  585. /* this is where each line is a document (good for databases) */
  586.  
  587. boolean one_line_hit_header = false;
  588.  
  589. boolean one_line_separator_function(line)
  590. char *line;
  591. {
  592.     return(true);
  593. }
  594.  
  595. char one_line_header[MAX_HEADER_LEN + 1];
  596.  
  597. void one_line_header_function(line)
  598. char *line;
  599. {
  600.     strncpy(one_line_header, line, MAX_HEADER_LEN);
  601. }
  602.  
  603. void one_line_finish_header_function(header)
  604. char *header;
  605. {
  606.   if (strlen(one_line_header) == 0) {
  607.     strcpy(header, "No Title");
  608.   }
  609.   else {
  610.     strncpy(header, one_line_header, MAX_HEADER_LEN);
  611.   }
  612.   one_line_header[0] = '\0';
  613. }
  614.  
  615. /* =============================
  616.  * ===  Paragraph Separator  ===
  617.  * =============================
  618.  */
  619.  
  620. /* paragraph files - seperated by a blank line.  Next line is the header */
  621.  
  622. char para_header[MAX_HEADER_LEN +1];
  623. static boolean para_start = true;
  624.  
  625. boolean para_separator_function(line)
  626. char *line;
  627. {
  628.   if (para_start == true) {
  629.     para_start = false;
  630.     return true;
  631.   }
  632.   if (strlen(line) < 2)
  633.     para_start = true;
  634.   return false;
  635. }
  636.  
  637. void para_header_function(line)
  638. char *line;
  639. {
  640.   if (para_header[0] == 0)
  641.     strncpy(para_header, line, MAX_HEADER_LEN);
  642. }
  643.  
  644. void para_finish_header_function(header)
  645. char *header;
  646. {
  647.   if (strlen(para_header) == 0) {
  648.     strcpy(header, "No Title");
  649.   }
  650.   else {
  651.     strncpy(header, para_header, MAX_HEADER_LEN);
  652.   }
  653.   para_header[0] = 0;
  654. }  
  655.  
  656. /* ==========================
  657.  * ===  Seeker Separator  ===
  658.  * ==========================
  659.  */
  660.  
  661. boolean seeker_separator_function(line)
  662. char *line;
  663. {
  664.   return(dash_separator_function(line));
  665. }
  666.  
  667. char seeker_header[MAX_HEADER_LEN + 1];
  668. boolean in_headline = FALSE;
  669.  
  670. void seeker_header_function(line)
  671. char *line;
  672. {
  673.   if(strlen(line) > strlen("Headline:") &&
  674.      substrcmp(line, "Headline:")){
  675.     in_headline = TRUE;
  676.     seeker_header[0] = '\0';
  677.     /* printf("hit headline!\n"); */
  678.   }
  679.   else if(in_headline == TRUE &&
  680.       (strlen(seeker_header) < (MAX_HEADER_LEN - 1))){
  681.     s_strncat(seeker_header, line, 
  682.           MAX_HEADER_LEN, MAX_HEADER_LEN);
  683.     trim_trailing_newline(seeker_header);
  684.   }
  685. }
  686.  
  687. void seeker_finish_header_function(header)
  688. char *header;
  689. {
  690.   if (strlen(seeker_header) == 0) {
  691.     strcpy(header, "No Title");
  692.   }
  693.   else {
  694.     strncpy(header, seeker_header, MAX_HEADER_LEN);
  695.   }
  696.   seeker_header[0] = '\0';
  697.   in_headline = TRUE;
  698. }  
  699.  
  700. /* ==========================
  701.  * ===  RLIN Separator  ===
  702.  * ==========================
  703.  */
  704.  
  705. boolean rlin_separator_function(line)
  706. char *line;
  707. {
  708.   return(dash_separator_function(line));
  709. }
  710.  
  711. char rlin_header[MAX_HEADER_LEN + 1];
  712. boolean rlin_in_headline = FALSE;
  713.  
  714. void rlin_header_function(line)
  715. char *line;
  716. {
  717.   if(rlin_separator_function(line)){
  718.     rlin_in_headline = TRUE;
  719.     rlin_header[0] = '\0';
  720.     /* printf("hit headline!\n"); */
  721.   }
  722.   else if(rlin_in_headline == TRUE &&
  723.       (strlen(rlin_header) < (MAX_HEADER_LEN - 1))){
  724.     s_strncat(rlin_header, line, 
  725.           MAX_HEADER_LEN, MAX_HEADER_LEN);
  726.     trim_trailing_newline(rlin_header);
  727.   }
  728. }
  729.  
  730. void rlin_finish_header_function(header)
  731. char *header;
  732. {
  733.   if (strlen(rlin_header) == 0) {
  734.     strcpy(header, "No Title");
  735.   }
  736.   else {
  737.     strncpy(header, rlin_header, MAX_HEADER_LEN);
  738.   }
  739.   rlin_header[0] = '\0';
  740.   in_headline = TRUE;
  741. }  
  742.  
  743. /* ========================================
  744.  * ===  MH_BBoard  Customizations     ====
  745.  * ========================================
  746.  */
  747.  
  748. /* gcardwel@uci.edu
  749. MH bboards use a series of control A's to do a blank line.. yuk!
  750. */
  751.  
  752. boolean mh_bboard_separator_function(line)
  753. char *line;
  754. {
  755.   static boolean blank_line = false;
  756.  
  757.   if((strlen(line) > strlen("BBoard-ID: ")) &&
  758.      substrcmp(line, "BBoard-ID: ") &&
  759.      blank_line == true){
  760.     blank_line = false;
  761.     return(true);
  762.   }
  763.   
  764.   if(!strcmp(line, "\001\001\001\001\n")){
  765.     blank_line = true;
  766.   }
  767.   else{
  768.     blank_line = false;
  769.   }
  770.   return (false);
  771. }
  772.  
  773.